package com.joizhang.seckill.controller;

import com.joizhang.seckill.utils.DeadLockThread;
import com.joizhang.seckill.utils.Result;
import com.joizhang.seckill.utils.ThreadSwap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
public class ProfileController {

    ExecutorService service = new ThreadPoolExecutor(
            4,
            10,
            0, TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(50),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * curl localhost:8080/cpu/loop
     * <p>
     * top -Hp 32805
     * printf '%x\n' 32826
     * jstack 32805 |grep -A 20 803a
     */
    @GetMapping("/cpu/loop")
    public void testCPULoop() throws InterruptedException {
        System.out.println("请求cpu死循环");
        Thread.currentThread().setName("loop-thread-cpu");
        int num = 0;
        while (true) {
            num++;
            if (num == Integer.MAX_VALUE) {
                System.out.println("reset");
            }
            num = 0;
        }
    }

    /**
     * <p>-Xms500m -Xmx500m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/heapdump.hprof -Xlog:gc*:logs/heaplog.log:time
     * <p>for i in {1..500}; do curl localhost:8080/memory/leak;done
     * <p>jstat -gc pid
     */
    @GetMapping(value = "/memory/leak")
    public Result<String> leak() {
        System.out.println("模拟内存泄漏");
        ThreadLocal<Byte[]> localVariable = new ThreadLocal<Byte[]>();
        // 为线程添加变量
        localVariable.set(new Byte[4096 * 1024]);
        return Result.success("ok");
    }

    /**
     * for i in {1..100}; do curl localhost:8080/cpu/test;done
     */
    @GetMapping("/cpu/test")
    public Result<String> testCPU() {
        System.out.println("请求cpu");
        Object lock1 = new Object();
        Object lock2 = new Object();
        service.submit(new DeadLockThread(lock1, lock2), "deadLookThread-" + new Random().nextInt());
        service.submit(new DeadLockThread(lock2, lock1), "deadLookThread-" + new Random().nextInt());
        return Result.success("ok");
    }

    /**
     * curl localhost:8080/thread/swap?num=100
     * <p>
     * `vmstat 1 10，表示每1秒打印一次，打印10次
     */
    @GetMapping(value = "/thread/swap")
    public Result<String> threadSwap(int num) {
        System.out.println("模拟线程切换");
        for (int i = 0; i < num; i++) {
            new Thread(new ThreadSwap(new AtomicInteger(0)), "thread-swap" + i).start();
        }
        return Result.success("ok");
    }

}
